package com.ruoyi.common.utils.easyExcel;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据+图片导入
 *
 * @author wss
 */
@Slf4j
public class EasyExcelUtil {


    private static String filePath="E:\\bat\\";

    /**
     * 图片处理
     */
    public static void imageProcess(MultipartFile file, List<ExcelVo> excelVos) {
        try {
            XSSFWorkbook book = new XSSFWorkbook(file.getInputStream());
            //方式1 获取sheet数量，采用下标方式遍历读取每个工作表数据
            int sheetsNos = book.getNumberOfSheets();
//            for (int sheetNo = 0; sheetNo < sheetsNos; sheetNo++) {
//                Sheet sheet = book.getSheetAt(sheetNo);
//                //...省略，内容为方式2
//            }
            //方式2 获取sheet数量，直接遍历读取每个工作表数据
            for (Sheet sheet : book) {
                XSSFSheet xssSheet = (XSSFSheet) sheet;
                //获取工作表中绘图包
                XSSFDrawing drawing = xssSheet.getDrawingPatriarch();
                if (drawing == null) {
                    break;
                }
                //获取所有图像形状
                List<XSSFShape> shapes = drawing.getShapes();
                //遍历所有形状
                for (XSSFShape shape : shapes) {
                    //获取形状在工作表中的顶点位置信息（anchor锚点）
                    XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor();
                    //图片形状在工作表中的位置, 所在行列起点和终点位置
                    short c1 = anchor.getCol1();
                    int r1 = anchor.getRow1();
                    String key = r1 + "行," + c1 + "列";
                    if (shape instanceof XSSFPicture) {
                        try {
                            XSSFPicture pic = (XSSFPicture) shape;
                            //形状获取对应的图片数据
                            XSSFPictureData picData = pic.getPictureData();
                            //保存图片到本地
                            byte[] data = picData.getData();
                            //TODO 这里上传文件至oss并生成链接，这里不做过多描述，有疑问请参照oss服务调用
                            String fileName = filePath + DateUtil.today() + "/" + IdUtil.simpleUUID() + "/" + picData.suggestFileExtension();
                            writeByteArrayToFile(data, fileName);

                            //fileTemplate.putObject(properties.getBucketName(), fileName, new ByteArrayInputStream(data));
                            //TODO 放入excel集合，这里行数要减去1，获取图片是从表头开始（表头位置为0），获取excelVos是从数据开始（第一条数据位置为0）他们相差一个表头，所以要减去1才能对应
                            excelVos.get(r1 - 1).setPicture(fileName);
                        } catch (Exception e) {
                            log.error("asyncImportList XSSFClientAnchor key|{} error|{}", key, e.getMessage());
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("asyncImportList XSSFWorkbook error|{}", e.getMessage());
        }
    }

    /**
     * 数据处理
     */
    public static void dataProcess(MultipartFile file, List<ExcelVo> excelVos) {
        // 这里默认读取第一个sheet
        try {
            EasyExcel.read(file.getInputStream(), ExcelVo.class, new ReadListener() {
                /**
                 * 单次缓存的数据量
                 */
                public static final int BATCH_COUNT = 100;
                /**
                 *临时存储
                 */
                private List<ExcelVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

                @Override
                public void invoke(Object object, AnalysisContext context) {
                    ExcelVo data = (ExcelVo) object;
                    cachedDataList.add(data);
                    if (cachedDataList.size() >= BATCH_COUNT) {
                        saveData();
                        // 存储完成清理 list
                        cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                    }
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    saveData();
                }

                /**
                 * 加上存储数据库
                 */
                private void saveData() {
                    log.info("已获取数据|{}条", cachedDataList.size());
                    excelVos.addAll(cachedDataList);
                }
            }).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void writeByteArrayToFile(byte[] data, String filePath) {
        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            fos.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}




